package com.kitty.game.fight.book;

import com.kitty.game.pet.model.PetBook;
import com.kitty.game.fight.bean.Fight;
import com.kitty.game.fight.bean.FightObject;
import com.kitty.game.fight.bean.PetFightObject;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.fight.message.RespAttackSkillLightEffect;
import com.kitty.game.fight.util.FightMessageUtil;
import com.kitty.game.fight.util.FightRateUtil;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public abstract class BookSkillProcessor {

    /**
     * 技能id-->效果处理器
     */
    static Map<String, BookSkillProcessor> skills = new HashMap<>();

    public static final String JING_LEI = "惊雷";
    public static final String QING_MU = "青木";
    public static final String HAN_BING = "寒冰";
    public static final String LIE_YAN = "烈炎";
    public static final String SUI_SHI = "碎石";
    public static final String XIAN_FENG = "仙风";
    public static final String MO_YIN = "魔引";
    public static final String NU_JI = "怒击";
    public static final String PO_TIAN = "破天";
    public static final String XIANG_MO = "降魔斩";
    public static final String FAN_JI = "反击";
    public static final String JIN_ZHONG = "尽忠";
    public static final String YUN_TI = "云体";
    public static final String XIU_LUO = "修罗术";


    public static final byte TYPE_DEF = 1;
    public static final byte TYPE_PHY = 2;
    public static final byte TYPE_MAG = 3;

    public static Set<String> mag = new HashSet<>(Arrays.asList("怒击", "降魔斩", "修罗术", "破天"));// 法攻
    public static Set<String> phy = new HashSet<>(Arrays.asList("魔引", "青木", "寒冰", "烈炎", "碎石", "惊雷", "破天"));// 物攻
    public static Set<String> def = new HashSet<>(Arrays.asList("反击", "云体", "仙风", "尽忠"));// 被动

    static {
        skills.put(JING_LEI, new JingLeiSkillProcessor());
        skills.put(QING_MU, new QingMuSkillProcessor());
        skills.put(HAN_BING, new HanBingSkillProcessor());
        skills.put(LIE_YAN, new LieYanSkillProcessor());
        skills.put(SUI_SHI, new SuiShiSkillProcessor());
        skills.put(NU_JI, new NuJiSkillProcessor());
        skills.put(MO_YIN, new MoYinSkillProcessor());
        skills.put(FAN_JI, new FanJiSkillProcessor());
    }

    public static BookSkillProcessor queryProcessor(String name) {
        return skills.get(name);
    }

    public static boolean attackTrigger(Fight fight, FightObject effector, FightObject target, String bookName) {
        if (effector == null || !effector.isPet()) {
            return false;
        }
        if (target != null && fight.isSameSide(effector, target)) {
            return false;
        }

        PetFightObject pet = (PetFightObject) effector;

        boolean result = false;
        int fightRound = fight.getRound();
        String nothing = "";
        Map<Integer, String> attackBooks = pet.getAttackBooks();
        try {
            if (bookName.equals(attackBooks.getOrDefault(fightRound, nothing))) {
                result = true;
                return result;
            }
            if (attackBooks.containsKey(fightRound)) {
                return false;
            }
            if (!BookSkillProcessor.isHit(effector)) {
                attackBooks.put(fightRound, nothing);
                return false;
            }

            byte attackType = FightRateUtil.isHit(50, 100) ? BookSkillProcessor.TYPE_PHY : BookSkillProcessor.TYPE_MAG;
            PetBook book = SpringUtils.getFightService().getPetFightBook(fight, effector, attackType);
            if (book == null) {
                attackBooks.put(fightRound, nothing);
                return false;
            } else {
                attackBooks.put(fightRound, book.getBookName());
            }

            result = book.getBookName().equals(bookName);
            return result;
        } finally {
            if (result) {
                playAnim(effector, fight, bookName);
            }
        }
    }

    public static boolean defenseTrigger(FightObject effector, Fight fight, String bookName) {
        if (effector == null || !effector.isPet()) {
            return false;
        }
        PetFightObject pet = (PetFightObject) effector;

        boolean result = false;
        int fightRound = fight.getRound();
        String nothing = "";
        Map<Integer, String> defenseBooks = pet.getDefenseBooks();
        try {
            if (bookName.equals(defenseBooks.getOrDefault(fightRound, nothing))) {
                result = true;
                return result;
            }
            if (defenseBooks.containsKey(fightRound)) {
                return false;
            }
            if (!BookSkillProcessor.isHit(effector)) {
                defenseBooks.put(fightRound, nothing);
                return false;
            }

            PetBook book = SpringUtils.getFightService().getPetFightBook(fight, effector, BookSkillProcessor.TYPE_DEF);
            if (book == null) {
                defenseBooks.put(fightRound, nothing);
                return false;
            } else {
                defenseBooks.put(fightRound, book.getBookName());
            }

            result = book.getBookName().equals(bookName);
            return result;
        } finally {
            if (result) {
                playAnim(effector, fight, bookName);
            }
        }
    }

    public static void playAnim(FightObject effector, Fight fight, String bookName) {
        RespAttackSkillLightEffect effect = SpringUtils.getFightMessageService().bookSkillEffect(effector.getId(),
                bookName);
        FightMessageUtil.sendFightPackage(fight, effect);
    }

    boolean commonCheck(Fight fight, FightObject effector, FightObject target) {
        if (!effector.isPet()) {
            return false;
        }
        FightObject hostObj = fight.queryFightObject(effector.getHostId());
        if (hostObj == null) {
            return false;
        }
        return true;
    }

    public static boolean isHit(FightObject fightObj) {
        if (!fightObj.isPet()) {
            return false;
        }
        PetFightObject pet = (PetFightObject) fightObj;
        int rate = (int) (pet.getLevel() * 1.6 * 0.2);
        rate = Math.max(1, rate);
        return FightRateUtil.isHit(rate, 100);
    }

    /**
     * 效果执行
     *
     * @param fight
     * @param effector
     * @param target
     * @param args
     */
    public abstract Object effect(Fight fight, FightObject effector, FightObject target, Object... args);
}
